package com.zt.sso.util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zt.sso.config.Property;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.Tuple;

public class RedisManager {

	public static final Logger logger = LoggerFactory.getLogger(RedisManager.class);

	/**
	 * 安全创建单例对象
	 */
	private static class StaticHolder {

		static final GenericObjectPoolConfig poolConfig;
		static final JedisSentinelPool jedisPool;

		static { // http://segmentfault.com/a/1190000000352578
			logger.info("init jedis pool");
			poolConfig = new GenericObjectPoolConfig();
			poolConfig.setMinIdle(Integer.valueOf(Property.getProperty("redis.minIdle", "2")));
			poolConfig.setMaxIdle(Integer.valueOf(Property.getProperty("redis.maxIdle", "5")));
			poolConfig.setMaxTotal(Integer.valueOf(Property.getProperty("redis.maxTotal", "10")));
			poolConfig.setMaxWaitMillis(Integer.valueOf(Property.getProperty("redis.maxWaitMillis", "5000")));
			poolConfig.setTestOnBorrow(Boolean.valueOf(Property.getProperty("redis.testOnBorrow", "true")));
			poolConfig.setTestWhileIdle(Boolean.valueOf(Property.getProperty("redis.testWhileIdle", "false")));
			int soTimeout = Integer.valueOf(Property.getProperty("redis.soTimeout", "2000"));
			String[] ipArray = StringUtils.split(Property.getProperty("redis.ips"), ',');
			Set<String> sentinels = new HashSet<String>();
			for (String ip : ipArray) {
				sentinels.add(ip);
			}
			jedisPool = new JedisSentinelPool(Property.getProperty("redis.mastname", "mymaster"), sentinels, poolConfig,
					soTimeout, Property.getProperty("redis.password", "smyredis"));
		}

	}

	public static JedisSentinelPool getJedisPool() {
		return StaticHolder.jedisPool;
	}

	/**
	 * 设置一个key的过期时间（单位：秒）
	 * 
	 * @param key
	 *            key值
	 * @param seconds
	 *            多少秒后过期
	 * @return 1：设置了过期时间 0：没有设置过期时间/不能设置过期时间
	 */
	public static long expire(String key, int seconds) {
		if (key == null || key.equals("")) {
			return 0;
		}

		logStart("RedisManager.expire", key, "ReisManager.expire(key=" + key + ",seconds=" + seconds + ")");
		Jedis jedis = null;
		long actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.expire(key, seconds);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("EXPIRE error[key=" + key + " seconds=" + seconds + "]" + ex.getMessage(), ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 设置一个key在某个时间点过期
	 * 
	 * @param key
	 *            key值
	 * @param unixTimestamp
	 *            unix时间戳，从1970-01-01 00:00:00开始到现在的秒数
	 * @return 1：设置了过期时间 0：没有设置过期时间/不能设置过期时间
	 */
	public static long expireAt(String key, int unixTimestamp) {
		if (key == null || key.equals("")) {
			return 0;
		}

		logStart("RedisManager.expireAt", key,
				"ReisManager.expireAt(key=" + key + ",unixTimestamp=" + unixTimestamp + ")");
		Jedis jedis = null;
		long actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.expireAt(key, unixTimestamp);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("EXPIRE error[key=" + key + " unixTimestamp=" + unixTimestamp + "]" + ex.getMessage(), ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 截断一个List
	 * 
	 * @param key
	 *            列表key
	 * @param start
	 *            开始位置 从0开始
	 * @param end
	 *            结束位置
	 * @return 状态码
	 */
	public static String trimList(String key, long start, long end) {
		if (key == null || key.equals("")) {
			return "-";
		}

		logStart("RedisManager.trimList", key,
				"ReisManager.trimList(key=" + key + ",start=" + start + ",end=" + end + ")");
		Jedis jedis = null;
		String actualRes = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.ltrim(key, start, end);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("LTRIM 出错[key=" + key + " start=" + start + " end=" + end + "]" + ex.getMessage(), ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 检查Set长度
	 * 
	 * @param key
	 * @return
	 */
	public static long countSet(String key) {
		if (key == null) {
			return 0;
		}

		logStart("RedisManager.countSet", key, "ReisManager.countSet(key=" + key + ")");
		Jedis jedis = null;
		long actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.scard(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("countSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 添加到Set中（同时设置过期时间）
	 * 
	 * @param key
	 *            key值
	 * @param seconds
	 *            过期时间 单位s
	 * @param value
	 * @return
	 */
	public static boolean addSet(String key, int seconds, String... value) {
		boolean result = addSet(key, value);
		if (result) {
			long i = expire(key, seconds);
			return i == 1;
		}

		return false;
	}

	/**
	 * 添加到Set中
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean addSet(String key, String... value) {
		if (key == null || value == null) {
			return false;
		}

		logStart("RedisManager.addSet", key, "ReisManager.addSet(key=" + key + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.sadd(key, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("setList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * @param key
	 * @param value
	 * @return 判断值是否包含在set中
	 */
	public static boolean containsInSet(String key, String value) {
		if (key == null || value == null) {
			return false;
		}

		logStart("RedisManager.containsInSet", key, "ReisManager.containsInSet(key=" + key + ",value=" + value + ")");
		Jedis jedis = null;
		boolean actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.sismember(key, value);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("setList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 获取Set
	 * 
	 * @param key
	 * @return
	 */
	public static Set<String> getSet(String key) {
		if (StringUtils.isEmpty(key)) {
			return null;
		}

		logStart("RedisManager.getSet", key, "ReisManager.getSet(key=" + key + ")");
		Jedis jedis = null;
		Set<String> actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.smembers(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 从set中删除value
	 * 
	 * @param key
	 * @return
	 */
	public static boolean removeSetValue(String key, String... value) {
		if (StringUtils.isEmpty(key)) {
			return false;
		}

		logStart("RedisManager.removeSetValue", key, "ReisManager.removeSetValue(key=" + key + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.srem(key, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 从list中删除value 默认count 1
	 * 
	 * @param key
	 * @param values
	 *            值list
	 * @return
	 */
	public static int removeListValue(String key, List<String> values) {
		return removeListValue(key, 1, values);
	}

	/**
	 * 从list中删除value
	 * 
	 * @param key
	 * @param count
	 * @param values
	 *            值list
	 * @return
	 */
	public static int removeListValue(String key, long count, List<String> values) {
		int result = 0;
		if (values != null && values.size() > 0) {
			for (String value : values) {
				if (removeListValue(key, count, value)) {
					result++;
				}
			}
		}

		return result;
	}

	/**
	 * 从list中删除value
	 * 
	 * @param key
	 * @param count
	 *            要删除个数
	 * @param value
	 * @return
	 */
	public static boolean removeListValue(String key, long count, String value) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
			return false;
		}

		logStart("RedisManager.removeListValue", key,
				"ReisManager.removeListValue(key=" + key + ",count=" + count + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.lrem(key, count, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 截取List
	 * 
	 * @param key
	 * @param start
	 *            起始位置
	 * @param end
	 *            结束位置
	 * @return
	 */
	public static List<String> rangeList(String key, long start, long end) {
		if (StringUtils.isEmpty(key)) {
			return null;
		}

		logStart("RedisManager.rangeList", key,
				"ReisManager.rangeList(key=" + key + ",start=" + start + ",end=" + end + ")");
		Jedis jedis = null;
		List<String> actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.lrange(key, start, end);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("rangeList 出错[key=" + key + " start=" + start + " end=" + end + "]" + ex.getMessage(), ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 检查List长度
	 * 
	 * @param key
	 * @return
	 */
	public static long countList(String key) {
		if (StringUtils.isEmpty(key)) {
			return 0;
		}

		logStart("RedisManager.countList", key, "ReisManager.countList(key=" + key + ")");
		Jedis jedis = null;
		long actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.llen(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("countList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 添加到List中（同时设置过期时间）
	 * 
	 * @param key
	 *            key值
	 * @param seconds
	 *            过期时间 单位s
	 * @param value
	 * @return
	 */
	public static boolean addList(String key, int seconds, String... value) {
		boolean result = addList(key, value);
		if (result) {
			long i = expire(key, seconds);
			return i == 1;
		}

		return false;
	}

	/**
	 * 添加到List
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean addList(String key, String... value) {
		if (StringUtils.isEmpty(key)) {
			return false;
		}

		logStart("RedisManager.addList", key, "ReisManager.addList(key=" + key + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.lpush(key, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("setList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 添加到List(只新增)
	 * 
	 * @param key
	 * @return
	 */
	public static boolean addList(String key, List<String> list) {
		if (key == null || list == null || list.size() == 0) {
			return false;
		}
		for (String value : list) {
			addList(key, value);
		}
		return true;
	}

	/**
	 * 获取List
	 * 
	 * @param key
	 * @return
	 */
	public static List<String> getList(String key) {
		if (StringUtils.isEmpty(key)) {
			return null;
		}

		logStart("RedisManager.getList", key, "ReisManager.getList(key=" + key + ")");
		Jedis jedis = null;
		List<String> actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.lrange(key, 0, -1);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getList error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 设置HashSet对象
	 * 
	 * @param domain
	 *            域名
	 * @param key
	 *            键值
	 * @param value
	 *            Json String or String value
	 * @return
	 */
	public static boolean setHSet(String domain, String key, String value) {
		if (StringUtils.isEmpty(domain) || StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
			return false;
		}

		logStart("RedisManager.setHSet", key,
				"ReisManager.setHSet(domain=" + domain + ",key=" + key + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.hset(domain, key, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("setHSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 获得HashSet对象
	 * 
	 * @param domain
	 *            域名
	 * @param key
	 *            键值
	 * @return Json String or String value
	 */
	public static String getHSet(String domain, String key) {
		if (StringUtils.isEmpty(domain) || StringUtils.isEmpty(key)) {
			return null;
		}

		logStart("RedisManager.getHSet", key, "ReisManager.setHSet(domain=" + domain + ",key=" + key + ")");
		Jedis jedis = null;
		String actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.hget(domain, key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getHSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 删除HashSet对象
	 * 
	 * @param domain
	 *            域名
	 * @param key
	 *            键值
	 * @return 删除的记录数
	 */
	public static long delHSet(String domain, String key) {
		if (StringUtils.isEmpty(domain) || StringUtils.isEmpty(key)) {
			return 0;
		}

		logStart("RedisManager.delHSet", key, "ReisManager.delHSet(domain=" + domain + ",key=" + key + ")");
		Jedis jedis = null;
		long count = 0;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			count = jedis.hdel(domain, key);
			return count;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("delHSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 删除HashSet对象
	 * 
	 * @param domain
	 *            域名
	 * @param key
	 *            键值
	 * @return 删除的记录数
	 */
	public static long delHSet(String domain, String... key) {
		if (StringUtils.isEmpty(domain)) {
			return 0;
		}

		logStart("RedisManager.delHSet", domain, "ReisManager.delHSet(domain=" + domain + ",key=" + key + ")");
		Jedis jedis = null;
		long count = 0;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			count = jedis.hdel(domain, key);
			return count;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("delHSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 判断key是否存在
	 * 
	 * @param domain
	 *            域名
	 * @param key
	 *            键值
	 * @return
	 */
	public static boolean existsHSet(String domain, String key) {
		if (StringUtils.isEmpty(domain) || StringUtils.isEmpty(key)) {
			return false;
		}

		logStart("RedisManager.existsHSet", key, "ReisManager.existsHSet(domain=" + domain + ",key=" + key + ")");
		Jedis jedis = null;
		boolean isExist = false;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			isExist = jedis.hexists(domain, key);
			return isExist;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("existsHSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 全局扫描hset
	 * 
	 * @param match
	 *            field匹配模式
	 * @return
	 */
	public static List<Map.Entry<String, String>> scanHSet(String domain, String match) {
		if (StringUtils.isEmpty(domain) || StringUtils.isEmpty(match)) {
			return null;
		}

		logStart("RedisManager.scanHSet", match, "ReisManager.scanHSet(domain=" + domain + ",match=" + match + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			int cursor = 0;
			jedis = getJedisPool().getResource();
			ScanParams scanParams = new ScanParams();
			scanParams.match(match);
			ScanResult<Map.Entry<String, String>> scanResult;
			List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>();
			do {
				scanResult = jedis.hscan(domain, String.valueOf(cursor), scanParams);
				list.addAll(scanResult.getResult());
				cursor = Integer.parseInt(scanResult.getStringCursor());
			} while (cursor > 0);

			return list;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("scanHSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 返回 domain 指定的哈希集中所有字段的value值
	 * 
	 * @param domain
	 * @return
	 */
	public static List<String> hvals(String domain) {
		if (StringUtils.isEmpty(domain)) {
			return null;
		}

		logStart("RedisManager.hvals", domain, "ReisManager.hvals(domain=" + domain + ")");
		Jedis jedis = null;
		List<String> retList = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			retList = jedis.hvals(domain);
			return retList;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("hvals error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 返回 domain 指定的哈希集中所有字段的key值
	 * 
	 * @param domain
	 * @return
	 */
	public static Set<String> hkeys(String domain) {
		if (StringUtils.isEmpty(domain)) {
			return null;
		}

		logStart("RedisManager.hkeys", domain, "ReisManager.hkeys(domain=" + domain + ")");
		Jedis jedis = null;
		Set<String> retList = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			retList = jedis.hkeys(domain);
			return retList;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("hkeys error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 返回 domain 指定的哈希key值总数
	 * 
	 * @param domain
	 * @return
	 */
	public static long lenHset(String domain) {
		if (StringUtils.isEmpty(domain)) {
			return 0;
		}

		logStart("RedisManager.lenHset", domain, "ReisManager.lenHset(domain=" + domain + ")");
		Jedis jedis = null;
		long retList = 0;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			retList = jedis.hlen(domain);
			return retList;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("hkeys error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 设置排序集合
	 * 
	 * @param key
	 * @param score
	 * @param value
	 * @return
	 */
	public static boolean setSortedSet(String key, long score, String value) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
			return false;
		}

		logStart("RedisManager.setSortedSet", key,
				"ReisManager.setSortedSet(key=" + key + ",score=" + score + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.zadd(key, score, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("setSortedSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 获得排序集合
	 * 
	 * @param key
	 * @param startScore
	 * @param endScore
	 * @param orderByDesc
	 * @return
	 */
	public static Set<String> getSoredSet(String key, long startScore, long endScore, boolean orderByDesc) {
		if (StringUtils.isEmpty(key)) {
			return null;
		}

		logStart("RedisManager.getSoredSet", key, "ReisManager.getSoredSet(key=" + key + ",startScore=" + startScore
				+ ",endScore=" + endScore + ",orderByDesc=" + orderByDesc + ")");
		Jedis jedis = null;
		Set<String> actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			if (orderByDesc) {
				actualRes = jedis.zrevrangeByScore(key, endScore, startScore);
			} else {
				actualRes = jedis.zrangeByScore(key, startScore, endScore);
			}

			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getSoredSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 计算排序长度
	 * 
	 * @param key
	 * @param startScore
	 * @param endScore
	 * @return
	 */
	public static long countSoredSet(String key, long startScore, long endScore) {
		if (StringUtils.isEmpty(key)) {
			return 0;
		}

		logStart("RedisManager.countSoredSet", key,
				"ReisManager.countSoredSet(key=" + key + ",startScore=" + startScore + ",endScore=" + endScore + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			Long count = jedis.zcount(key, startScore, endScore);
			count = count == null ? 0L : count;
			return count;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("countSoredSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 删除排序集合
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean delSortedSet(String key, String value) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
			return false;
		}

		logStart("RedisManager.delSortedSet", key, "ReisManager.delSortedSet(key=" + key + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			long count = jedis.zrem(key, value);
			boolean isDel = count > 0;
			return isDel;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("delSortedSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 获得排序集合
	 * 
	 * @param key
	 * @param startRange
	 * @param endRange
	 * @param orderByDesc
	 * @return
	 */
	public static Set<String> getSoredSetByRange(String key, int startRange, int endRange, boolean orderByDesc) {
		if (StringUtils.isEmpty(key)) {
			return null;
		}

		logStart("RedisManager.getSoredSetByRange", key,
				"ReisManager.getSoredSetByRange(key=" + key + ",startRange=" + startRange + ")");
		Jedis jedis = null;
		Set<String> actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			if (orderByDesc) {
				actualRes = jedis.zrevrange(key, startRange, endRange);
			} else {
				actualRes = jedis.zrange(key, startRange, endRange);
			}

			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getSoredSetByRange error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static double zincrby(String key, double score, String member) {
		logStart("RedisManager.zincrby", key, "ReisManager.zincrby(key=" + key + ",score=" + score + ")");
		Jedis jedis = null;
		double actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.zincrby(key, score, member);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("zincrby error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static Set<Tuple> zrevrangeWithScores(String key, long start, long end) {
		logStart("RedisManager.zrevrangeWithScores", key,
				"ReisManager.zrevrangeWithScores(key=" + key + ",start=" + start + ",end=" + end + ")");
		Jedis jedis = null;
		Set<Tuple> actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.zrevrangeWithScores(key, start, end);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("zrevrangeWithScores error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static Long zrank(String key, String member) {
		logStart("RedisManager.zrank", key, "ReisManager.zrank(key=" + key + ",member=" + member + ")");
		Jedis jedis = null;
		Long actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.zrank(key, member);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("zrank error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static Long zrevrank(String key, String member) {
		logStart("RedisManager.zrevrank", key, "ReisManager.zrevrank(key=" + key + ",member=" + member + ")");
		Jedis jedis = null;
		Long actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.zrevrank(key, member);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("zrevrank error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static Set<String> zrevrange(String key, long start, long end) {
		logStart("RedisManager.zrevrange", key,
				"ReisManager.zrevrange(key=" + key + ",start=" + start + ",end=" + end + ")");
		Jedis jedis = null;
		Set<String> actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.zrevrange(key, start, end);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("zrevrange error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 获得排序打分
	 * 
	 * @param key
	 * @return
	 */
	public static Double getScore(String key, String member) {
		logStart("RedisManager.getScore", key, "ReisManager.getScore(key=" + key + ",member=" + member + ")");
		Jedis jedis = null;
		Double actualRes;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			actualRes = jedis.zscore(key, member);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("getSoredSet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static boolean set(String key, String value, int second) {
		logStart("RedisManager.set", key, "ReisManager.set(key=" + key + ",value=" + value + ",second=" + second + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.setex(key, second, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("set error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static boolean set(String key, String value) {
		logStart("RedisManager.set", key, "ReisManager.set(key=" + key + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.set(key, value);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("set error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static String get(String key, String defaultValue) {
		logStart("RedisManager.get", key, "ReisManager.get(key=" + key + ",defaultValue=" + defaultValue + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			String actualRes = jedis.get(key) == null ? defaultValue : jedis.get(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("get error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static boolean del(String key) {
		logStart("RedisManager.del", key, "ReisManager.del(key=" + key + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			jedis.del(key);
			return true;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("del error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 批量删除key
	 * 
	 * @param keys
	 *            待删除的key数组
	 * @return
	 */
	public static boolean del(String[] keys) {
		Jedis jedis = null;

		try {
			jedis = getJedisPool().getResource();
			jedis.del(keys);

			return true;
		} catch (Exception ex) {
			logger.error("del error.", ex);

			throw ex;
		} finally {
			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static long incr(String key) {
		logStart("RedisManager.incr", key, "ReisManager.incr(key=" + key + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			long actualRes = jedis.incr(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("incr error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static long decr(String key) {
		logStart("RedisManager.decr", key, "ReisManager.decr(key=" + key + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			long actualRes = jedis.decr(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("decr error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 
	 * @param map
	 * @return
	 */
	public static void setByPipeline(Map<String, String> map) {
		if (null == map) {
			return;
		}

		logStart("RedisManager.setByPipeline", "N/A", "ReisManager.setByPipeline() size:" + map.size());
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			Pipeline pipe = jedis.pipelined();
			Set<String> keySet = map.keySet();
			for (String key : keySet) {
				pipe.set(key, map.get(key));
			}

			pipe.sync();
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("setByPipeline error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	/**
	 * 批量获取
	 * 
	 * @param keys
	 * @return
	 */
	public static List<String> mget(String... keys) {
		logStart("RedisManager.mget", keys.toString(), "ReisManager.mget()");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			List<String> actualRes = jedis.mget(keys);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("mGet error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static Map<String, String> hgetAll(String key) {
		logStart("RedisManager.hgetAll", key, "ReisManager.hgetAll(key=" + key + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			Map<String, String> actualRes = jedis.hgetAll(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("hgetAll error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static Boolean exists(String key) {
		logStart("RedisManager.exists", key, "ReisManager.exists(key=" + key + ")");

		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			Boolean actualRes = jedis.exists(key);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("exists error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static String hget(String key, String field) {
		logStart("RedisManager.hget", key, "ReisManager.hget(key=" + key + ",field=" + field + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			String actualRes = jedis.hget(key, field);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("hget error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static String hmset(String key, Map<String, String> hash) {
		logStart("RedisManager.hmset", key, "ReisManager.hmset(key=" + key + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			String actualRes = jedis.hmset(key, hash);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("hmset error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	public static Long hsetnx(String key, String field, String value) {
		logStart("RedisManager.hsetnx", key,
				"ReisManager.hsetnx(key=" + key + ",field=" + field + ",value=" + value + ")");
		Jedis jedis = null;
		System.currentTimeMillis();
		try {
			jedis = getJedisPool().getResource();
			Long actualRes = jedis.hsetnx(key, field, value);
			return actualRes;
		} catch (Exception ex) {
			ex.getMessage();
			logger.error("hsetnx error.", ex);

			throw ex;
		} finally {

			if (null != jedis) {
				jedis.close();
			}
		}
	}

	private static void logStart(String string, String key, String string2) {
		logger.info(string + ":{}" + string2, key);

	}

}
